#pragma once

#include "fxcc/core/graph/opengl3/pch.h"

namespace fxcc
{
	namespace graph
	{
		namespace opengl3
		{
			struct FXCC_API DepthStencilDesc
			{
				bool m_EnableDepthFunc;
				bool m_EnableStencilFunc;

				int m_DepthFunc;

				int m_StencilFunc;
				int m_StencilRef;
				int m_StencilRefMask;

				int m_StencilWriteMask;
				int m_StencilFail, m_DepthFail, m_DepthStencilPass;

				DepthStencilDesc() :
					m_EnableDepthFunc(true),
					m_DepthFunc(GL_LESS),
					m_EnableStencilFunc(false),
					m_StencilFunc(GL_ALWAYS),
					m_StencilRef(0),
					m_StencilRefMask(0),
					m_StencilWriteMask(0xFF),
					m_StencilFail(GL_KEEP),
					m_DepthFail(GL_KEEP),
					m_DepthStencilPass(GL_KEEP)
				{
				}
				void Use() const
				{
					if (m_EnableDepthFunc) {
						glEnable(GL_DEPTH_TEST);
						glDepthFunc(m_DepthFunc);
					}
					else {
						glDisable(GL_DEPTH_TEST);
					}

					if (m_EnableStencilFunc) {
						glEnable(GL_STENCIL_TEST);
						glStencilFunc(m_StencilFunc, m_StencilRef, m_StencilRefMask);
						glStencilMask(m_StencilWriteMask);
						glStencilOp(m_StencilFail, m_DepthFail, m_DepthStencilPass);
					}
					else {
						glDisable(GL_STENCIL_TEST);
					}
				}
			};

			struct FXCC_API BlendDesc
			{
				bool m_EnableBlend;
				int m_Sfactor, m_Dfactor;
				BlendDesc() :m_EnableBlend(false), m_Sfactor(GL_SRC_ALPHA), m_Dfactor(GL_ONE_MINUS_SRC_ALPHA)
				{

				}
				void Use() const
				{
					if (m_EnableBlend)
					{
						glEnable(GL_BLEND);
						glBlendFunc(m_Sfactor, m_Dfactor);
					}
					else
					{
						glDisable(GL_BLEND);
					}
				}
			};

			struct FXCC_API RasterizerDesc {

				int m_PolyMode;
				int m_PolyFillMode;
				bool m_EnableCullface;
				int m_Cullface;
				int m_FrontFace;

				RasterizerDesc()
					:
					m_PolyMode(GL_FRONT_AND_BACK),
					m_PolyFillMode(GL_FILL),
					m_EnableCullface(true),
					m_Cullface(GL_BACK),
					m_FrontFace(GL_CCW)
				{

				}
				void Use() const
				{
					glPolygonMode(m_PolyMode, m_PolyFillMode);

					if (m_EnableCullface) {
						glEnable(GL_CULL_FACE);
						glFrontFace(m_FrontFace);
						glCullFace(m_Cullface);
					}
					else {
						glDisable(GL_CULL_FACE);
						glCullFace(GL_NONE);
					}

				};
			};
		};
	};
};